/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.bff.designtime.generator.api.entityinterface.resourceinfo;

import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.utils.ExpressionUtils;
import com.inspur.edp.cef.designtime.api.IGspCommonDataType;
import com.inspur.edp.cef.entity.condition.SortCondition;
import com.inspur.edp.cef.entity.condition.SortType;
import com.inspur.edp.cef.generator.apiGenerator.dataType.entityInterface.resourceInfo.ResourceInfoCtorGenerator;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import io.iec.edp.caf.common.JSONSerializer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.springframework.util.StringUtils;

public class BffResourceInfoCtorGenerator extends ResourceInfoCtorGenerator {
    private IGspCommonObject dataType;

    protected BffResourceInfoCtorGenerator(String className, IGspCommonDataType dataType) {
        super(className, dataType);
        this.dataType = (IGspCommonObject) dataType;
    }

    @Override
    protected void addExtendStatements(Block block) {
        List<SortCondition> sorts = getSorts();
        if (sorts.isEmpty()) {
            return;
        }

        MethodInvocation setSortInvocation = ast.newMethodInvocation();
        setSortInvocation.setName(ast.newSimpleName("setSorts"));
        setSortInvocation.arguments().add(buildSortsArgs(sorts));
        block.statements().add(ast.newExpressionStatement(setSortInvocation));
    }

    private Expression buildSortsArgs(List<SortCondition> sorts) {
        addImport(SortCondition.class.getTypeName());
        MethodInvocation asListInvocation = ast.newMethodInvocation();
        asListInvocation.setExpression(ast.newName(Arrays.class.getTypeName()));
        asListInvocation.setName(ast.newSimpleName("asList"));
        for (SortCondition sort : sorts) {
            ClassInstanceCreation sortCreation = ast.newClassInstanceCreation();
            sortCreation.setType(new TypeInfo(SortCondition.class).getType(ast));
            sortCreation.arguments().add(ExpressionUtils.getStringLiteral(ast, getFieldPath(
                (GspCommonObject) dataType, sort.getSortField())));
            sortCreation.arguments().add(ast.newQualifiedName(ast.newName(SortType.class.getTypeName()),
                ast.newSimpleName(sort.getSortType().toString())));
            asListInvocation.arguments().add(sortCreation);
        }
        return asListInvocation;
    }

    private static String getFieldPath(GspCommonObject node, String labelId) {
        IGspCommonElement element = node.getElementByLabelId(labelId);
        if(element == null) {
            throw new RuntimeException("模型" + node.getBelongModel().getCode() + "的节点" + node.getCode() + "上设置的排序字段" + labelId + "不存在, 请重新设置排序字段.");
        }
        if(element.getParentAssociation() != null) {
            return element.getParentAssociation().getBelongElement().getLabelID() + "." + element.getLabelID();
        } else {
            return element.getLabelID();
        }
    }

    private List<SortCondition> getSorts() {
        String orderByStr = dataType.getOrderbyCondition();
        if (StringUtils.isEmpty(orderByStr)) {
            return Collections.emptyList();
        }
        try {
            return JSONSerializer.deserialize(orderByStr, List.class, SortCondition.class);
        } catch (Exception e) {
            throw new RuntimeException(
                dataType.getBelongModel() != null ? dataType.getBelongModel().getCode()
                    : "" + "节点" + dataType.getCode() + "定义的排序条件格式不正确, 请检查", e);
        }
    }
}
